//
// Created by Administrator on 2019/12/10.
//
#include <iostream>
#include <cstring>
#include <string>

using namespace std;


// 结构体
struct Book {
    char title[50];
    char author[50];
    char subject[100];
    int book_id;
};


// 引用的使用
void print1() {
    int i;
    double d;
    int &ii = i;
    double &dd = d;
    i = 5;
    cout << "value of i = " << i << endl;
    cout << "value of i reference = " << ii << endl;

    dd = 5.5;
    cout << "value of d = " << d << endl;
    cout << "value of d reference = " << dd << endl;

}

// 结构体测试
void print2() {
    Book book1, book2;
    strcpy(book1.title, "C++");
    strcpy(book1.author, "虾仁");
    strcpy(book1.subject, "编程语言");
    book1.book_id = 1;

    strcpy(book2.title, "javascript");
    strcpy(book2.author, "tom");
    strcpy(book2.subject, "前端技术");
    book2.book_id = 2;

    // 输出 Book1 信息
    cout << "第一本书标题 : " << book1.title << endl;
    cout << "第一本书作者 : " << book1.author << endl;
    cout << "第一本书类目 : " << book1.subject << endl;
    cout << "第一本书 ID : " << book1.book_id << endl;

    // 输出 Book2 信息
    cout << "第二本书标题 : " << book2.title << endl;
    cout << "第二本书作者 : " << book2.author << endl;
    cout << "第二本书类目 : " << book2.subject << endl;
    cout << "第二本书 ID : " << book2.book_id << endl;

}

// 2.protected 继承：基类 public 成员，protected 成员，private 成员的访问属性在派生类中分别变成：protected, protected, private
class Person {

public:
    const char *name = "defaultName"; // 名称
    Person() {
        cout << "Person构造函数执行" << endl;
    }

    Person(int age) {
        this->age = age;
    }

    void setName(char *name) {
        this->name = name;
    }

    virtual void infoNo() {};  // 虚函数

    friend string getArrInfo2(Person person);

protected:
    int age = 0;    // 年龄

private:
    const char *idCard = "421126191902020030";

    friend string getArrInfo(Person person);


};

string getArrInfo(Person person) {
    const char *cName = person.name;
    const char *cIdCard = person.idCard;
    string x = cName;
    string cc = "name = " + x + ", idCard = " + cIdCard;
    return cc;
}

string notFriendInfo(Person person) {
    const char *cName = person.name;
//    const char *cIdCard = person.idCard;      // 非友元函数，无法访问private
    string x = cName;
    string cc = "name = " + x;
    return cc;
}

// 类相关测试
void print3() {
    cout << "print3()<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<," << endl;
//    Person a();
//    a.setName("b")  // 报错,这种情况，是编译器将其识别为，申明函数a()返回值为Person的函数声明
    Person *aa = new Person(30);  // 这种情况是，
    char bbb[] = "bbb";
    aa->setName(bbb);
    cout << "a()-----" << endl;
    Person b[3];
    char c1[] = "tom1", c2[] = "tom2", c3[] = "tom3";
    b->setName(c1);
    b[1].setName(c2);
    b[2].setName(c3);

    cout << "b[3]-----" << endl;
    Person *p[4];
    cout << "*p[4]-----" << endl;

    Person *pp = &b[1], *ppp = new Person[4];
    char d1[] = "ddddd2-name";
    ppp[2].setName(d1);
    cout << "name->" << pp->name << endl;
    cout << "named->" << (ppp + 1)->name << endl;
    cout << "named->" << (ppp + 2)->name << endl;

}
// 测试一波友元类访问本类中的所有成员函数或方法

void print4() {
    cout << "print4()<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<," << endl;
    Person person;
    string c1 = getArrInfo(person);
    string c2 = notFriendInfo(person);
    char c3[] = "dddd";

    cout << "friendFunc->" << c1 << ", notFriendFunc->" << c2 << ", c3->" << c3 << endl;

    char s[100] = "hello world";
    //1.计算字符串的长度
    int length = strlen(s);
    printf("length=%d\n", length);
    //2.字符串的拼接或追加
    char s2[100] = "abcefg";
    strcat(s, s2);//将s2拼接到s后面
    cout << "s = " << s << endl;

    char cc[100] = "hello world";
    char cc2[100] = "追爱记哦的";
    strcat(cc, cc2);
    cout << "cc = " << cc << endl;

}
// 测试一波抽象类

class Shape {

    int height = 0;     // 默认是私有的



public:
    int length = 0;

    virtual void info() = 0;    // 纯虚函数

    Shape(){
        cout << "Shape()无参构造函数" << endl;
    }

    Shape(int length){
        this->length = length;
        cout << "Shape()有参构造函数" << endl;
    }

    ~Shape(){
        cout << "Shape()析构函数" << this->length << endl;
    }

};

class Rectangle : public Shape {

    int width = 99;

    void info() override {
        cout << "my is Student public info function" << endl;
    }



public:
    int getLength() {
        return this->length;
    }

    Rectangle(){
        cout << "这个是Rectangle构造方法" << this->getLength() << endl;
    }

    Rectangle(int length){
        this->length = length;
        cout << "这个是Rectangle有参构造方法, this.length = " << this->length << endl;
    }

    ~Rectangle(){
        cout << "这个是Rectangle构造方法" << this->length << endl;
    }
};

class Rectangle2 : protected Shape {
public:
    static Rectangle2 rectangle2;
    int age = 50;

    void printInfo(char *p);

protected:
    void info() override {
        cout << "my is Student1 protected info function" << endl;
    }
};

void Rectangle2::printInfo(char *p) {
    printf("随便打印下内容而已->%s", p);
}

// 继承类
void print5() {
    cout << "print5()<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<," << endl;

    Shape *shape1 = new Rectangle();
    shape1->length = 10;
    shape1->info();

//    shape2->info();
    cout << "shape1->length = " << shape1->length << endl;

    Rectangle2 *rectangle2 = new Rectangle2(), rectangle20;


    cout << "rectangle2->age = " << rectangle2->age << "rectangle20->age = " << rectangle20.age << endl;

    rectangle2->printInfo("xxxxx");
}

// 测试一波函数默认值的设定

// 测试一波内敛函数
// （1）在内联函数内不允许用循环语句和开关语句；（2）内联函数的定义必须出现在内联函数第一次被调用之前；（3）后续学到的类结构中所有在类说明内部定义的函数都是内联函数。

inline int chengfa(int x, int y) {
    for (int i = 0; i < 10; ++i) {
        x += 1;
        if (i > 5) {
            break;
        }
    }
    return x * y;
}

double sqrt(double x = 1.0);

double sqrt(double x) {
    return x * x;
}

int f(int i1, int i2 = 2, int i3 = 3);     // 正确
//int g(int i1, int i2 = 2, int i3);         // 错误, i3未指定默认值
//int h(int i1 = 1, int i2, int i3 = 3);     // 错误, i2未指定默认值
//int k(int i1 = 5, int i2);      // i2需要置顶

// 内联函数，函数默认值设置
void print6() {
    cout << "print6()<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<," << endl;
    cout << chengfa(20, 50) << endl;

    /**
     * 1、默认值说明：有函数声明(原型)时,默认参数可以放在函数声明或者定义中，但只能放在二者之一
     * 2、在具有多个参数的函数中指定默认值时,默认参数都必须出现在不默认参数的右边,一旦某个参数开始指定默认值,它右边的所有参数都必须指定默认值.
     */

    cout << "sqrt()默认值打印:" << sqrt() << ", sqrt(5.0)打印：" << sqrt(5.0) << endl;
}

// 测试一波delete语句
void print7(){
    cout << "print7()<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<," << endl;

    Shape *shape = new Rectangle(10);
    Rectangle *shape1 = new Rectangle();

    cout << "shape -- 需要使用delete(shape)才可能调用析构函数" << endl;

    Rectangle rectangle, *rectangle1 = new Rectangle();
    rectangle.length = 11;
    rectangle1->length = 22;
    cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << rectangle.getLength() << endl;
    // 执行new申请空间的对象析构函数
    delete(rectangle1);
    shape1->length = 33;
    cout << "bbbbb" << shape1->length << endl;
    delete shape1;

    cout << "程序结束" << endl;


}

class Base {
public:
    Base(){
        cout << "这个是Base()构造函数" << endl;
    }
    ~Base(){
        cout << "这个是~Base()析构函数" << endl;
    }
};

class Son: public Base {
public:
    Son(){
        cout << "这个是Son()构造函数" << endl;
    }
    ~Son(){
        cout << "这个是~Son()析构函数" << endl;
    }
};

// 测试一波析构函数，构造函数调用顺序
void print8(){
    cout << "print8()<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<," << endl;

//    Son son;
//    Base base;
//    Base *baseNew = new Base();
    cout << "下面这种情况，delete的时候，仅执行了父类的析构函数" << endl;
    Base *sonNew = new Son();
    delete sonNew;

    cout << "xxxxxxxxxxxxxxxx" << endl;
    Son *son1 = new Son();
    delete son1;

}

// 声明一波函数试试
char Fun(int, double) ;

// 测试一波虚函数与纯虚函数区别
void print9(){
    cout << "print9()<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<," << endl;

}

// 测试一波delete用法
void print10(){
    cout << "print10()<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<," << endl;
    int *i1 = new int(100);
    cout << "*i1=" << *i1 << endl;
    delete i1;
    cout << "*i1=" << *i1 << endl;

}


